/** 
 * createStore(reducer, preloadState, enhance)
 * getState 获取状态
 * subscribe
 * dispatch 触发action
 * enhance 是对功能的扩展 接受createStore参数 返回一个接收reducer，preloadedState参数的函数 该函数时对store的扩展重写
*/

function createStore (reducer, preloadState, enhancer) {
    console.log(preloadState)
    // reducer 类型判断 
    if (typeof reducer !== 'function') throw new Error('redcuer必须是函数');
    if (typeof enhancer !== 'undefined') {
        if (typeof enhancer !== 'function') {
            throw new Error('enhancer必须是函数')
        }
        // 当存在enhance函数就在enhance中创建store
        return enhancer(createStore)(reducer, preloadState);
    }
    
    //当前状态
    var currentState = preloadState
    // 订阅状态列表
    const listeners = []
    // 获取状态
 
    function getState() {
        return currentState
    }
    // 触发action
    function dispatch(action) {
         // 判断action是否是一个对象
        if (!isPlainObject(action)) throw new Error('action必须是一个对象');
        // 判断action中的type属性是否存在
        if (typeof action.type === 'undefined') throw new Error('action对象中必须有type属性');
        currentState = reducer(currentState, action)
        listeners.forEach(listener => {
            listener()
        })
    }
    // 订阅状态发生改变改变
    function subscribe(listener) {
        listeners.push(listener)
    }
    
    return {
        getState,
        dispatch,
        subscribe
    }
}


function bindActionCreators (actionCreators,  dispatch) {
    var bindActionCreators = {}
    for (let key in actionCreators) {
        bindActionCreators[key] = () => dispatch(actionCreators[key]())
    }
    return bindActionCreators
}


// 判断参数是否是对象类型
// 判断对象的当前原型对象是否和顶层原型对象相同
function isPlainObject (obj) {
    if (typeof obj !== 'object' || obj === null) return false;
    var proto = obj;
    while (Object.getPrototypeOf(proto) != null) {
      proto = Object.getPrototypeOf(proto)
    }
    return Object.getPrototypeOf(obj) === proto;
}
// applyMiddleWare 中间件
function applyMiddleWare (...middleWares) {
    return function (createStore) {
        return function (reducer, preloadState) {
            // 创建 store
            var store = createStore(reducer, preloadState);
            // 阉割版的 store
            var middlewareAPI = {
                getState: store.getState,
                dispatch: store.dispatch
            }
            let chain = middleWares.map(middleWare => middleWare(middlewareAPI))
            let dispatch = compose(chain)(store.dispatch)
            return {
                ...store,
                dispatch
            }
        }
    }
}

function compose(chain) {
    return function (dispatch) {
        for (let i = chain.length - 1; i >= 0; i-- ) {
            dispatch = chain[i](dispatch)
        }
        return dispatch
    }
}

// 实现reducer合并
function combineReducers(reducers) {
    // 1. 检查reducer类型 它必须是函数
    var reducerKeys = Object.keys(reducers);
    for (var i = 0; i < reducerKeys.length; i++) {
        var key = reducerKeys[i];
        if (typeof reducers[key] !== 'function') throw new Error('reducer必须是函数');
    }
    // 2. 调用一个一个的小的reducer 将每一个小的reducer中返回的状态存储在一个新的大的对象中
    return function (state, action) {
        console.log(state)
        var nextState = {};
        for (var i = 0; i < reducerKeys.length; i++) {
            var key = reducerKeys[i];
            var reducer = reducers[key];
            var previousStateForKey = state[key];
            console.log(key)
            nextState[key] = reducer(previousStateForKey, action)
        }
        return nextState;
    }

}